package handler

import (
	"encoding/hex"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"log"
	"strings"
	"tianlian-ttc/internal/pkg/packet"
	"tianlian-ttc/internal/pkg/udpserver"
)

// SatelliteTargetMap maps satellite codes to target codes
var SatelliteTargetMap = map[string]string{
	"xr7":   "1b6501",
	"xr09":  "1c6501",
	"sjy01": "2f6501",
}

// GetTargetCode converts satellite code to target code
func GetTargetCode(satelliteCode string) (string, error) {
	// Convert to lowercase for case-insensitive comparison
	satCode := strings.ToLower(satelliteCode)
	if targetCode, ok := SatelliteTargetMap[satCode]; ok {
		return targetCode, nil
	}
	return "", fmt.Errorf("unknown satellite code: %s", satelliteCode)
}

// ControlHandler handles control commands
type ControlHandler struct {
	config udpserver.PacketConfig
}

type CmdOrder struct {
	SatelliteCode string `json:"satelliteCode" form:"satelliteCode" gorm:"column:satellite_code;comment:卫星编号;size:50;"`
	CmdData       string `json:"cmdData" form:"cmdData" gorm:"column:cmd_data;comment:指令数据;"`
}

// NewControlHandler creates a new ControlHandler
func NewControlHandler() *ControlHandler {
	packetConfig := udpserver.PacketConfig{
		SourceID:      uint32(viper.GetInt("server.udp.packet.source_id")),
		DestinationID: uint32(viper.GetInt("server.udp.packet.destination_id")),
	}
	return &ControlHandler{
		config: packetConfig,
	}
}

// SendControlCommand sends a control command via UDP
func (h *ControlHandler) SendControlCommand(c *gin.Context) {
	var cmdOrder CmdOrder
	if err := c.ShouldBindJSON(&cmdOrder); err != nil {
		c.JSON(400, gin.H{"error": "Invalid request format"})
		return
	}

	if cmdOrder.CmdData == "" {
		c.JSON(400, gin.H{"error": "Command is required"})
		return
	}

	if cmdOrder.SatelliteCode == "" {
		c.JSON(400, gin.H{"error": "Satellite code is required"})
		return
	}

	// Convert satellite code to target code
	targetCode, err := GetTargetCode(cmdOrder.SatelliteCode)
	if err != nil {
		c.JSON(400, gin.H{"error": fmt.Sprintf("Invalid satellite code: %v", err)})
		return
	}

	// Decode command data
	decodeString, err := hex.DecodeString(strings.Replace(cmdOrder.CmdData, " ", "", -1))
	if err != nil {
		c.JSON(400, gin.H{"error": fmt.Sprintf("Invalid command data: %v", err)})
		return
	}

	// Decode target code
	targetCodeBytes, err := hex.DecodeString(targetCode)
	if err != nil {
		c.JSON(400, gin.H{"error": fmt.Sprintf("Invalid target code: %v", err)})
		return
	}

	//linkMonitorPacket := packet.NewDataPacket(
	//	h.config.SourceID,
	//	h.config.DestinationID,
	//	targetCodeBytes,
	//	decodeString,
	//)
	linkMonitorPacket := packet.NewControlPacket(
		h.config.SourceID,
		h.config.DestinationID,
		targetCodeBytes, // Target code
		false,           // Enable loopback (true for 0xF0, false for 0x0F)
		decodeString,    // Your control frame data
		true,            // Set to true for immediate execution
	)
	// 使用现有的UDP连接发送指令
	// Use existing UDP connection to send command

	log.Println("使用现有的UDP连接发送指令" + hex.EncodeToString(linkMonitorPacket.Bytes()))
	err = udpserver.SendCommand(linkMonitorPacket.Bytes())
	if err != nil {
		log.Println("Error sending UDP packet:", err)
		c.JSON(500, gin.H{"error": "Internal server error"})
		return
	}

	c.JSON(200, gin.H{"code": 200, "message": "Command sent successfully"})
}
